package com.seven.commons;

import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.slf4j.*;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * @author sevenDay
 * @classname ${CLASSNAME}
 * @description: 描述TODO
 * @date 2018/2/23
 */
@Slf4j
public class SpringBeanValidatorUtils {

    private static final String VALUE_RESULT_TEMPLATE = ", 当前值为[%s]";

    private static  final  Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * 进行方法的一般的参数的校验操作
     * @param obj
     * @param method
     * @param params
     * @param <T>
     * @return
     */
    public  static <T>  String validate( Method method, Object[] params,T obj, Class<?>[] group){

        final Set<ConstraintViolation<T>> set = validMethodParams(obj, method, params,group);
        ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
        if (!set.isEmpty()) {
            // 获得方法的参数名称
            String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
            // 获得校验的参数路径信息
            for(ConstraintViolation<T> constraintViolation : set) {
                PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
                // 获得校验的参数位置
                int paramIndex = pathImpl.getLeafNode().getParameterIndex();
                // 获得校验的参数名称
                String paramName = parameterNames[paramIndex];

                log.info(paramName);
                //校验信息
                log.info(constraintViolation.getMessage());
            }
            //返回第一条
            return set.iterator().next().getMessage() + String.format(VALUE_RESULT_TEMPLATE, set.iterator().next().getInvalidValue());
        }
        return null;
    }


    /**
     * 校验普通的参数方法和实现
     * @param obj
     * @param method
     * @param params
     * @param <T>
     * @return
     */
    private static  <T> Set<ConstraintViolation<T>> validMethodParams(T obj, Method method, Object[] params,Class<?>[] group) {

        return validator.forExecutables().validateParameters(obj, method, params);
    }
}
